package com.ss.utils;


import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.apache.poi.poifs.crypt.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.Security;

public class ExportEncryptExcelTools {
    public static void main(String[] args) throws Exception {
        // 第一步：使用 Apache POI 创建一个 Excel 工作簿
        Workbook workbook = new XSSFWorkbook();  // 创建一个新的 XSSFWorkbook，表示一个 Excel 文件
        Sheet sheet = workbook.createSheet("Sheet1");  // 在工作簿中创建一个名为 "Sheet1" 的工作表

        // 创建第一行，并向其中的单元格写入数据
        Row row = sheet.createRow(0);  // 创建第一行（索引为 0）
        Cell cell = row.createCell(0);  // 在第一行创建第一个单元格
        cell.setCellValue("Hello, World!");  // 在单元格中写入 "Hello, World!" 字符串

        // 将工作簿写入到一个未加密的 Excel 文件中
        String filePath = "unEncrypt.xlsx";  // 未加密 Excel 文件的文件路径
        try (FileOutputStream fileOut = new FileOutputStream(filePath)) {
            workbook.write(fileOut);  // 将工作簿内容写入文件
        }
        workbook.close();  // 写入完成后关闭工作簿，释放资源

        // 第二步：使用 Bouncy Castle 添加密码保护
        Security.addProvider(new BouncyCastleProvider());  // 添加 Bouncy Castle 提供者以支持加密

        // 创建一个新的 POIFSFileSystem 对象，用于保存加密的数据
        POIFSFileSystem fs = new POIFSFileSystem();

        // 创建加密信息，使用 Agile 模式（现代 Office 文件使用的加密模式）
        EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
        Encryptor encryptor = info.getEncryptor();  // 创建一个加密器
        encryptor.confirmPassword("dxj");  // 设置加密文件的密码

        // 使用 OPCPackage 打开未加密的 Excel 文件
        try (OPCPackage opc = OPCPackage.open(new File(filePath), PackageAccess.READ_WRITE);
             OutputStream os = encryptor.getDataStream(fs)) {
            opc.save(os);  // 将未加密的 Excel 数据写入到加密流中
        }

        // 将加密后的 Excel 文件保存为一个新文件
        try (FileOutputStream fos = new FileOutputStream("encrypt.xlsx")) {
            fs.writeFilesystem(fos);  // 将文件系统内容写入文件
        }

        System.out.println("带有密码的 Excel 文件已成功创建！");
    }
}

